package com.rk.jarjuggler.gui;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.TableColumn;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.treetable.ListTreeTableModelOnColumns;
import com.intellij.util.ui.treetable.TreeTable;
import com.rk.jarjuggler.model.DirNode;
import com.rk.jarjuggler.model.LibNode;
import com.rk.jarjuggler.service.DirFileStore;

public class TreeTablePanel extends JPanel {
    private DirSearchParams searchParams;
    private DirNode originalRoot;
    private TreeTableView treeTableView;
    private ActionListener addLibraryAction;
    private JButton addButton;

    public TreeTablePanel() {
        this(null);
        setAddAction(new SaveAction());
    }

    public TreeTablePanel(ActionListener addLibraryAction) {
        this.addLibraryAction = addLibraryAction;
        setLayout(new BorderLayout());

        searchParams = new DirSearchParams();
        searchParams.addPropertyChangeListener(new FilterPropertyChange());
        originalRoot = DirFileStore.loadTree();

        treeTableView = new TreeTableView(new DirNodeTreeTableModel(originalRoot));
        treeTableView.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        add(new SearchPanel(searchParams), BorderLayout.NORTH);
        add(new JScrollPane(treeTableView), BorderLayout.CENTER);
        add(createDetailPanel(), BorderLayout.SOUTH);

        setSizes(treeTableView);
    }

    public java.util.List<LibNode> getSelectedPackages(){
        java.util.List<LibNode> selectedItems = new ArrayList<LibNode>();
        for (Object o : treeTableView.getSelection()) {
            selectedItems.add((LibNode) o);
        }
        return selectedItems;
    }

    public void setAddAction(ActionListener action){
        addButton.addActionListener(action);
    }

    private JPanel createDetailPanel(){
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel("Selected Library"));
        final JTextField textField = new JTextField();
        addButton = new JButton("Add Library");
        addButton.setEnabled(false);

        treeTableView.getTree().addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
                TreePath path = treeSelectionEvent.getPath();
                DirNode dirNode = (DirNode) path.getLastPathComponent();
                String test = path == null ? "" : dirNode.getFullName();
                textField.setText(test);

                addButton.setEnabled(dirNode instanceof LibNode);
            }
        });

        textField.setPreferredSize(new Dimension(400, (int) textField.getPreferredSize().getHeight()));
        panel.add(textField);
        addButton.addActionListener(addLibraryAction);
        panel.add(addButton);
        return panel;
    }

    protected static DirNode filterTree(DirNode root, DirSearchParams searchParams){
        DirNode newRoot = new DirNode(null, root.getName(), root.getUrl());
        for (DirNode child : root.getDirNodeChildren()) {
             if (child.passesFilter(searchParams.getSearchText(), searchParams.isHasJar(), searchParams.isHasSource(), searchParams.isHasJavadoc())) {
                 newRoot.addChildDir(child);
             }
        }
        return newRoot;
    }

    protected void filterTree(final DirSearchParams searchParams){
        if (!searchParams.hasCriteria()) {
            return;
        }

        final DirNodeTreeTableModel treeModel = (DirNodeTreeTableModel)treeTableView.getTableModel();

        DirNode newRoot = filterTree(originalRoot, searchParams);
        treeModel.setRoot(newRoot);

//        new SwingWorker() {
//            public Object construct() {
//                DirNode newRoot = filterTree(originalRoot, searchParams);
//                return newRoot;
//            }
//
//            public void finished() {
//                TreeNode newRoot = (TreeNode) getValue();
//                treeModel.setRoot(newRoot);
//            }
//        }.start();
    }

    public static void main(String[] args) {
        TreeTablePanel panel = new TreeTablePanel();
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    private void setSizes(TreeTable treeTable) {
      ColumnInfo[] columns = ((ListTreeTableModelOnColumns)treeTable.getTableModel()).getColumns();
      for (int i = 0; i < columns.length; i++) {
        ColumnInfo columnInfo = columns[i];
        TableColumn column = treeTable.getColumnModel().getColumn(i);
        if (columnInfo.getWidth(treeTable) > 0) {
          int width = columnInfo.getWidth(treeTable);
          column.setMaxWidth(width);
          column.setMinWidth(width);
        }
      }
    }


//    class ExpandAllAction extends AbstractAction {
//        public ExpandAllAction() {
//            super("Expand All");
//        }
//
//        public void actionPerformed(ActionEvent actionEvent) {
//        }
//    }
//
//    class CollapseAllAction extends AbstractAction {
//        public CollapseAllAction() {
//            super("Collapse All");
//        }
//
//        public void actionPerformed(ActionEvent actionEvent) {
//            JTree tree = treeTableView.getTree();
//            tree.collapsePath(tree.getPathForRow(0));
//        }
//    }

    class FilterPropertyChange implements PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
            filterTree(searchParams);
        }
    }

    class SaveAction implements ActionListener {
        public void actionPerformed(ActionEvent actionEvent) {

            java.util.List<LibNode> selectedNodes = getSelectedPackages();
            for (LibNode libNode : selectedNodes) {
                System.out.println("libNode.getu = " + libNode.getJarUrl());
                try {
                    File tempFile = FileUtil.createTempFile(libNode.getName(), "jar");
                    com.rk.jarjuggler.service.HttpUtil.copyFile(libNode.getJarUrl(), tempFile);

                } catch (IOException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }

        }
    }
}

